package com.weareint.common.dto;

import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.weareint.common.exceptions.SystemRuntimeException;

import java.util.Objects;

/**
 *
 *
 * <pre>
 *      所有支持的操作符
 * </pre>
 *
 * @author wangg
 * @date 2021/7/1010:59
 */
public class Oprs {

    /**
     *
     *
     * <pre>
     *     通过参数操作符获取对应的Enum
     * </pre>
     *
     * @param opr 操作符
     * @return {@link Opr}
     */
    public static Opr getOprEnum(String opr) {
        if (null == opr) {
            return null;
        }
        opr = opr.toLowerCase();
        Opr[] values = Opr.values();
        for (Opr value : values) {
            if (Objects.equals(value.val.toLowerCase(), opr)) {
                return value;
            }
        }
        return null;
    }

    /** 查询的操作类型 */
    public enum Opr {
        /** 相等 */
        EQ("eq") {
            @Override
            protected <T, M extends AbstractWrapper<T, String, M>> void internalDecorate(
                    AbstractWrapper<T, String, M> wrapper, String column, Object value) {
                wrapper.eq(column, value);
            }
        },
        LT("lt") {
            @Override
            protected <T, M extends AbstractWrapper<T, String, M>> void internalDecorate(
                    AbstractWrapper<T, String, M> wrapper, String column, Object value) {
                wrapper.lt(column, value);
            }
        },
        LE("le") {
            @Override
            protected <T, M extends AbstractWrapper<T, String, M>> void internalDecorate(
                    AbstractWrapper<T, String, M> wrapper, String column, Object value) {
                wrapper.le(column, value);
            }
        },
        GT("gt") {
            @Override
            protected <T, M extends AbstractWrapper<T, String, M>> void internalDecorate(
                    AbstractWrapper<T, String, M> wrapper, String column, Object value) {
                wrapper.gt(column, value);
            }
        },
        GE("ge") {
            @Override
            protected <T, M extends AbstractWrapper<T, String, M>> void internalDecorate(
                    AbstractWrapper<T, String, M> wrapper, String column, Object value) {
                wrapper.ge(column, value);
            }
        },
        /** like 模糊查找 */
        LIKE("like") {
            @Override
            protected <T, M extends AbstractWrapper<T, String, M>> void internalDecorate(
                    AbstractWrapper<T, String, M> wrapper, String column, Object value) {
                wrapper.like(column, value);
            }
        },
        /** like 左匹配 */
        LIKE_LEFT("like_left") {
            @Override
            protected <T, M extends AbstractWrapper<T, String, M>> void internalDecorate(
                    AbstractWrapper<T, String, M> wrapper, String column, Object value) {
                wrapper.likeLeft(column, value);
            }
        },
        /** like 右匹配 */
        LIKE_RIGHT("left_right") {
            @Override
            protected <T, M extends AbstractWrapper<T, String, M>> void internalDecorate(
                    AbstractWrapper<T, String, M> wrapper, String column, Object value) {
                wrapper.likeRight(column, value);
            }
        };

        private final String val;

        Opr(String val) {
            this.val = val;
        }

        public <T, M extends AbstractWrapper<T, String, M>> void decorate(
                AbstractWrapper<T, String, M> wrapper, String type, String column, String val) {
            if (null == wrapper || null == type || null == column || null == val) {
                throw new SystemRuntimeException("arguments must be not null.");
            }
            Types.Type typeEnum = Types.getTypeEnum(type);
            if (null == typeEnum) {
                throw new SystemRuntimeException("Not Found type for " + type);
            }
            Object value = typeEnum.cast(val);
            internalDecorate(wrapper, column, value);
        }

        protected abstract <T, M extends AbstractWrapper<T, String, M>> void internalDecorate(
                AbstractWrapper<T, String, M> wrapper, String column, Object value);
    }
}
